package com.yesep.learn.netty.tcp.client;

import java.nio.charset.Charset;

import com.yesep.learn.netty.tcp.protocol.common.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.ReadTimeoutHandler;

public class NettyClient {
	private static final Logger log = LoggerFactory.getLogger(NettyClient.class);

	private Bootstrap bootstrap = null;
	private EventLoopGroup worker = null;
	private String url = null;
	private Integer port = null;
	private ChannelFuture cf = null;

	public NettyClient(String url, Integer port) throws InterruptedException {
		worker = new NioEventLoopGroup();
		bootstrap = new Bootstrap();
		bootstrap.group(worker).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
			@Override
			protected void initChannel(SocketChannel sc) throws Exception {
				ChannelPipeline pipeline = sc.pipeline();
				Charset charset = Charset.forName(Constants.CHARSET);
				pipeline.addLast(new StringDecoder(charset));
				pipeline.addLast(new StringEncoder(charset));
				pipeline.addLast(new ReadTimeoutHandler(60));// 设置超时时间
				pipeline.addLast(new ClientHandlerAdapter());
			}
		});
		this.url = url;
		this.port = port;
	}

	private void connect(String url, Integer port) throws InterruptedException {
		cf = bootstrap.connect(url, port).sync();
	}

	public ChannelFuture getChannelFuture() throws InterruptedException {
		if (this.cf == null) {
			this.connect(url, port);
		}
		if (!this.cf.channel().isActive()) {
			this.connect(url, port);
		}
		return this.cf;
	}

	public void writeAndFlush(Object msg) throws InterruptedException {
		getChannelFuture().channel().writeAndFlush(msg);
	}

	public void shutdown() throws InterruptedException {
		worker.shutdownGracefully();
	}
}